#pragma once

#include "Message.hpp"
#include "Communication.hpp"

namespace xu
{
    //v2 -实例出不同消息类型
    class Callback
    {
    public:
        using Ptr = std::shared_ptr<Callback>;
        virtual ~Callback() = default;
        virtual void onMessage(const BaseConnection::Ptr &conn,const  BaseMessage::Ptr &msg) = 0;
    };

    template <typename T>
    class CallbackT : public Callback
    {
    public:
        using Ptr = std::shared_ptr<CallbackT<T>>;
        using handler_t = std::function<void(const BaseConnection::Ptr &,const std::shared_ptr<T>&)>;
        
        CallbackT(handler_t handler)
        :_handler(handler)
        {}

        virtual void onMessage(const BaseConnection::Ptr &conn,const  BaseMessage::Ptr &msg) override
        {
            auto type_msg = std::dynamic_pointer_cast<T>(msg);
            _handler(conn,type_msg);
        }

    private:
        handler_t _handler;
    };

    class Dispatcher
    {
    public:
        using Ptr = std::shared_ptr<Dispatcher>;

        Dispatcher(){}
        //注册
        template <typename T>
        void registerHandler(MType mtype, const typename CallbackT<T>::handler_t &handler) 
        {
            std::unique_lock<std::mutex> _lock(_mutex);
            _handlers[mtype] = std::make_shared<CallbackT<T>>(handler);
        }


        //分发
        void onMessage(const BaseConnection::Ptr &conn, BaseMessage::Ptr &msg)
        {
            std::unique_lock<std::mutex> _lock(_mutex);
            auto it = _handlers.find(msg->Mtype());
            if(it == _handlers.end())
            {
                LOG(LogLevel::ERROR)<<"找不到该类型" <<(int)msg->Mtype()<<"的回调函数";
                return;
            }

            it->second->onMessage(conn,msg);
        }

        ~Dispatcher(){}
    private:
        std::mutex _mutex; //_mp属于临界资源，需要使用_mutex
        std::unordered_map<MType,Callback::Ptr> _handlers;//类型与函数的映射
    };


    //v1
    // class Dispatcher
    // {
    // public:
    //     using Ptr = std::shared_ptr<Dispatcher>;

    //     Dispatcher(){}
    //     //注册
    //     void registerHandler(MType mtype, const MessageCallback &handler) 
    //     {
    //         std::unique_lock<std::mutex> _lock(_mutex);
    //         _mp[mtype] = handler;
    //     }


    //     //分发
    //     void onMessage(const BaseConnection::Ptr &conn, BaseMessage::Ptr
    //         &msg)
    //     {
    //         std::unique_lock<std::mutex> _lock(_mutex);
    //         auto it = _mp.find(msg->Mtype());
    //         if(it == _mp.end())
    //         {
    //             return;
    //         }

    //         it->second(conn,msg);
    //     }

    //     ~Dispatcher(){}
    // private:
    //     std::mutex _mutex; //_mp属于临界资源，需要使用_mutex
    //     std::unordered_map<MType,MessageCallback> _mp;//类型与函数的映射
    // };


    class DispatcherFactory
    {
    public:
        template <typename... Args>
        static Dispatcher::Ptr create(Args &&...args)
        {
            return std::make_shared<Dispatcher>(std::forward<Args>(args)...);
        }
    };

};